﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StockFinder.Systemtester;
using StockFinder.Applications.Main;
using System.Diagnostics;
using System.IO;
using StockFinder.DataAccess;
using StockFinder.Indicators.Day;
using StockFinder.Indicators.Day.ClosePrice;
using StockFinder.Indicators.Day.Volume;
using StockFinder.Indicators.Day.HighPrice;
using StockFinder.Indicators.Day.LowPrice;
using StockFinder.NorgatePremiumData;
using System.Data.SqlClient;
using StockFinder.Model;
using log4net;

namespace Testharness
{
    public partial class LaunchControlForm : Form
    {
        private static readonly ILog _Log = LogManager.GetLogger(typeof(LaunchControlForm));

        public LaunchControlForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IndicatorsTestForm indicatorsForm = new IndicatorsTestForm();
            indicatorsForm.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            NorgatePremiumDataTestForm form = new NorgatePremiumDataTestForm();
            form.ShowDialog();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            PriceAnalyserTestForm form = new PriceAnalyserTestForm();
            form.ShowDialog();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            SystemTesterForm form = new SystemTesterForm();
            form.ShowDialog();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            YahooFinanceTestForm form = new YahooFinanceTestForm();
            form.ShowDialog();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            
        }

        private void button7_Click(object sender, EventArgs e)
        {
            var form = new GoogleFinanceTestForm();
            form.ShowDialog();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            var form = new IBDTestForm();
            form.ShowDialog();
        }

        private void button9_Click(object sender, EventArgs e)
        {
            var form = new CodeSnippetsForm();
            form.ShowDialog();
        }

        private void button10_Click(object sender, EventArgs e)
        {
            var form = new StockListForm();
            form.ShowDialog();
        }

        private void button6_Click_1(object sender, EventArgs e)
        {
            var form = new UIControlsForm();
            form.ShowDialog();
        }

        private void _ScenariosButton_Click(object sender, EventArgs e)
        {
            var form = new ScenarioTestForm();
            form.ShowDialog();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            var form = new PriceMoveFinderTestForm();
            form.ShowDialog();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            _Log.InfoFormat("Truncating PriceData");

            //1 truncate price data table
            DailyPriceDataAccess.TruncatePriceDataTable();

            _Log.InfoFormat("Truncating Symbols");

            //2 truncate symbols table
            SymbolDataAccess.TruncateSymbolTable();            

            //3 extract price histories
            const string PARENT_DIRECTORY = @"C:\Data\PriceHistory\Norgate\";

            SqlConnection connection = new SqlConnection(ApplicationConfiguation.DatabaseConnectionString);
            connection.Open();

            SqlBulkCopy bulkCopy = new SqlBulkCopy(connection,
                        SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null);

            DataTable priceDataTable = new DataTable("PriceData");
            priceDataTable.Columns.Add("SymbolId", typeof(int));
            priceDataTable.Columns.Add("PriceDate", typeof(DateTime));
            priceDataTable.Columns.Add("Open", typeof(decimal));
            priceDataTable.Columns.Add("High", typeof(decimal));
            priceDataTable.Columns.Add("Low", typeof(decimal));
            priceDataTable.Columns.Add("Close", typeof(decimal));
            priceDataTable.Columns.Add("AdjustedClose", typeof(decimal));
            priceDataTable.Columns.Add("Volume", typeof(decimal));
            priceDataTable.Columns.Add("RelativeStrength", typeof(decimal));

            bulkCopy.DestinationTableName = "PriceData";

            foreach (DataColumn column in priceDataTable.Columns)
            {
                bulkCopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
            }

            var indicators = new List<BaseDayIndicator>()
            {                
                new SimpleMovingAverageClosePriceDayIndicator(50, "MovingAverage50"),
                new SimpleMovingAverageClosePriceDayIndicator(200, "MovingAverage200"),                
                new ExponentialMovingAverageTrueRangeClosePriceDayIndicator(20, "Atr20"),
                new ExponentialMovingAverageTrueRangePercentOfClosePriceDayIndicator(20, "AtrPercentClose20"),
                new SimpleMovingAverageDailyVolumeDayIndicator(22, "AverageVolume22"),
                new SimpleMovingAveragePercentOfDailyVolumeDayIndicator(22, "PercentFromAverageVolume22"),
                new SimpleMovingAverageDailyVolumeDayIndicator(66, "AverageVolume66"),
                new SimpleMovingAveragePercentOfDailyVolumeDayIndicator(66, "PercentFromAverageVolume66"),
                new MaxHighPriceDayIndicator(252, "High52Week"),
                new MinLowPriceDayIndicator(252, "Low52Week"),
                new ExponentialMovingAverageWilderRelativeStrengthIndexClosePriceDayIndicator(14, "Rsi14"),
                new ExponentialMovingAverageWilderRelativeStrengthIndexClosePriceDayIndicator(20, "Rsi20"),
                new DonchianUpperChannelHighPriceDayIndicator(10, "DonchianUpper10"),
                new DonchianUpperChannelHighPriceDayIndicator(20, "DonchianUpper20"),
                new DonchianUpperChannelHighPriceDayIndicator(55, "DonchianUpper55"),
                new DonchianUpperChannelHighPriceDayIndicator(10, "DonchianLower10"),
                new DonchianUpperChannelHighPriceDayIndicator(20, "DonchianLower20"),
                new DonchianUpperChannelHighPriceDayIndicator(55, "DonchianLower55"),
                new YearPricePerformanceClosePriceIndicator("YearPerformance"),
            };

            var norgateExtractor = new NorgatePremiumDataStockFilePathsExtractor();

            var priceHistories = norgateExtractor.GetStockPriceHistoryFilenamesIncludingDelisted(PARENT_DIRECTORY);

            var priceHistoriesCount = priceHistories.Count();

            for (int i = 0; i < priceHistoriesCount; i++)
            {
                try
                {
                    var priceHistoryFilename = priceHistories[i];

                    var symbol = norgateExtractor.GetSymbolNameFromFileName(priceHistoryFilename);

                    var exchange = norgateExtractor.GetExchangeNameFromFileName(priceHistoryFilename);

                    _Log.DebugFormat("Symbol: {0}, Exchange: {1}", symbol, exchange);

                    var prices = norgateExtractor.GetStockPriceHistoryFromFilename(priceHistoryFilename);

                    priceDataTable.Rows.Clear();

                    int symbolId = SymbolDataAccess.InsertSymbol(symbol, exchange);

                    indicators.ForEach(ind => ind.ApplyIndicator(prices));

                    foreach (var pricedate in prices)
                    {
                        var row = priceDataTable.NewRow();
                        row["SymbolId"] = symbolId;

                        //add normal price and vol
                        row["Open"] = pricedate.Open;
                        row["High"] = pricedate.High;
                        row["Low"] = pricedate.Low;
                        row["Close"] = pricedate.Close;
                        row["Volume"] = pricedate.Volume;
                        row["PriceDate"] = pricedate.PriceDate;
                        row["AdjustedClose"] = pricedate.AdjustedClose;
                        row["AdjustedOpen"] = pricedate.AdjustedOpen;
                        row["AdjustedHigh"] = pricedate.AdjustedHigh;
                        row["AdjustedLow"] = pricedate.AdjustedLow;

                        //get indiciator info
                        indicators.ForEach(ind => row[ind.IndicatorName] = pricedate.DayIndicators[ind.IndicatorName]);

                        priceDataTable.Rows.Add(row);
                    }

                    bulkCopy.WriteToServer(priceDataTable);

                    _Log.Info(priceDataTable.Rows.Count);

                    _Log.InfoFormat("{0:0.0%} completed", (double)i / priceHistoriesCount);
                }
                catch (Exception exception)
                {
                    _Log.Error(exception);
                }                 
            }
        }

        private void button13_Click(object sender, EventArgs e)
        {
            #region Truncate

            _Log.InfoFormat("Truncating PriceData table");

            //1 truncate price data table
            DailyPriceDataAccess.TruncatePriceDataTable();

            _Log.InfoFormat("Truncating Symbols table");

            //2 truncate symbols table
            SymbolDataAccess.TruncateSymbolTable();

            _Log.InfoFormat("Truncating PriceDataPerformance table");

            //3 truncate price performance
            DailyPriceDataAccess.TruncatePriceDataPerformanceTable();

            #endregion

            #region PriceDataPerformance DataTable definition

            DataTable symbolPerformanceTable = new DataTable("PriceDataPerformance");
            symbolPerformanceTable.Columns.Add("SymbolId", typeof(int));            
            symbolPerformanceTable.Columns.Add("Open", typeof(decimal));
            symbolPerformanceTable.Columns.Add("High", typeof(decimal));
            symbolPerformanceTable.Columns.Add("Low", typeof(decimal));
            symbolPerformanceTable.Columns.Add("Close", typeof(decimal));            
            symbolPerformanceTable.Columns.Add("Volume", typeof(Int64));
            symbolPerformanceTable.Columns.Add("PriceDate", typeof(DateTime));
            symbolPerformanceTable.Columns.Add("AdjustedClose", typeof(decimal));
            symbolPerformanceTable.Columns.Add("Performance", typeof(decimal));

            #endregion

            #region Generate PriceDate performance

            using (var connection = new SqlConnection(ApplicationConfiguation.DatabaseConnectionString))
            {
                connection.Open();

                using (var bulkCopy = new SqlBulkCopy(connection,
                    SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null))
                {
                    bulkCopy.DestinationTableName = "PriceDataPerformance";

                    const string YEAR_PERFORMANCE = "YearPerformance";
                    var yearPerformanceIndicator = new YearPricePerformanceClosePriceIndicator(YEAR_PERFORMANCE);                    

                    var norgateExtractor = new NorgatePremiumDataStockFilePathsExtractor();

                    _Log.Info("Getting price history filenames");

                    var priceHistories = norgateExtractor.GetStockPriceHistoryFilenamesIncludingDelisted(
                        ApplicationConfiguation.NorgatePriceHistoryDirectory);

                    var priceHistoriesCount = priceHistories.Count();

                    _Log.InfoFormat("Analysing {0} price histories", priceHistoriesCount);

                    for (int i = 0; i < priceHistoriesCount; i++)
                    {
                        try
                        {
                            var priceHistoryFilename = priceHistories[i];

                            #region Insert symbol information

                            var symbol = norgateExtractor.GetSymbolNameFromFileName(priceHistoryFilename);

                            var exchange = norgateExtractor.GetExchangeNameFromFileName(priceHistoryFilename);

                            _Log.DebugFormat("Symbol: {0}, Exchange: {1}", symbol, exchange);

                            var prices = norgateExtractor.GetStockPriceHistoryFromFilename(priceHistoryFilename);

                            symbolPerformanceTable.Rows.Clear();

                            int symbolId = SymbolDataAccess.InsertSymbol(symbol, exchange);

                            #endregion

                            #region Get and update pricedate performance

                            yearPerformanceIndicator.ApplyIndicator(prices);

                            foreach (var pricedate in prices)
                            {
                                var row = symbolPerformanceTable.NewRow();
                                row["SymbolId"] = symbolId;
                                row["Open"] = pricedate.Open;
                                row["High"] = pricedate.High;
                                row["Low"] = pricedate.Low;
                                row["Close"] = pricedate.Close;
                                row["Volume"] = pricedate.Volume;
                                row["PriceDate"] = pricedate.PriceDate;
                                row["AdjustedClose"] = pricedate.AdjustedClose;
                                row["Performance"] = pricedate.DayIndicators[YEAR_PERFORMANCE];

                                symbolPerformanceTable.Rows.Add(row);
                            }

                            bulkCopy.WriteToServer(symbolPerformanceTable);

                            #endregion

                            _Log.Info(symbolPerformanceTable.Rows.Count);

                            _Log.InfoFormat("{0:0.0%} completed", (double)i / priceHistoriesCount);
                        }
                        catch (Exception exception)
                        {
                            _Log.Error(exception.ToString());
                        }
                    }
                }
            }

            #endregion
        }
    }
}
